package org.artifact.core.plugin.rpc.registry.zookeeper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.I0Itec.zkclient.ZkClient;
import org.artifact.core.plugin.rpc.registry.ServiceDiscovery;
import org.artifact.core.plugin.zookeeper.ZooKeeperPlugin;
import org.artifact.core.server.ServerPlugins;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 基于 ZooKeeper 的服务发现接口实现
 *
 * @author huangyong
 * @since 1.0.0
 */
public class ZooKeeperServiceDiscovery implements ServiceDiscovery {

    private static final Log log = LogFactory.get(ZooKeeperServiceDiscovery.class);


    @Override
    public String discover(String name) {
        // 创建 ZooKeeper 客户端
        ZkClient zkClient = ServerPlugins.me().getPlugin(ZooKeeperPlugin.class).getClient();
        log.debug("connect zookeeper");
        // 获取 service 节点
        String servicePath = Constant.ZK_REGISTRY_PATH + "/" + name;
        if (!zkClient.exists(servicePath)) {
            throw new RuntimeException(String.format("can not find any service node on path: %s", servicePath));
        }
        List<String> addressList = zkClient.getChildren(servicePath);
        if (CollUtil.isEmpty(addressList)) {
            throw new RuntimeException(String.format("can not find any address node on path: %s", servicePath));
        }
        // 获取 address 节点
        String address;
        int size = addressList.size();
        if (size == 1) {
            // 若只有一个地址，则获取该地址
            address = addressList.get(0);
            log.debug("get only address node: {}", address);
        } else {
            // 若存在多个地址，则随机获取一个地址
            address = addressList.get(ThreadLocalRandom.current().nextInt(size));
            log.debug("get random address node: {}", address);
        }
        // 获取 address 节点的值
        String addressPath = servicePath + "/" + address;
        return zkClient.readData(addressPath);
    }
}